package com.jabo.wechatmomentsdemo.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.AttributeSet;

import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.widget.AppCompatImageView;

import com.jabo.wechatmomentsdemo.R;


/**
 * 自定义圆角ImageView
 * 圆角大小可绘制，可以添加描边，遮罩等功能
 * @anthor JZheng3
 * @Time: 2020/9/6
 */
public class RoundImageView extends AppCompatImageView {

    public static final int DEFAULT_STROKE_COLOR = Color.GRAY;
    public static final int DEFAULT_MASK_COLOR = Color.parseColor("#66000000");
    private static final int MAX_SCALE_MODE = 1;
    private static final int MIN_SCALE_MODE = 2;

    //声明对象
    private Paint mPaint;
    private BitmapShader mBitmapShader;
    private Matrix mBitmapMatrix;

    //设置默认的尺寸和颜色
    private float mLeftRoundRadius;//默认是10
    private float mRightRoundRadius;
    private int mStrokeWidth;
    private int mStrokeColor;
    private int mMaskColor;

    //设置默认的属性
    private boolean mDrawMask;//默认不开起遮罩蒙版
    private PaintFlagsDrawFilter mPaintFlagsDrawFilter;
    private int mScaleMode = MAX_SCALE_MODE;


    public RoundImageView(Context context) {
        this(context, null);
    }

    public RoundImageView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RoundImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundImageView);
        mDrawMask = typedArray.getBoolean(R.styleable.RoundImageView_setMask, false);
        mMaskColor = typedArray.getColor(R.styleable.RoundImageView_maskColor, DEFAULT_MASK_COLOR);
        mStrokeColor = typedArray.getColor(R.styleable.RoundImageView_strokeColor, DEFAULT_STROKE_COLOR);
        mLeftRoundRadius = typedArray.getDimension(R.styleable.RoundImageView_leftRadius, 10);
        mRightRoundRadius = typedArray.getDimension(R.styleable.RoundImageView_rightRadius, 10);
        mStrokeWidth = (int) typedArray.getDimension(R.styleable.RoundImageView_strokeWidth, 0);
        mScaleMode = typedArray.getInt(R.styleable.RoundImageView_scaleMode, MAX_SCALE_MODE);
        typedArray.recycle();

        init();
    }

    private void init() {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);//看锯齿，对绘制bitmap不生效
        mBitmapMatrix = new Matrix();
        //抗锯齿，加强对绘制Bitmap生效
        mPaintFlagsDrawFilter = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onDraw(Canvas canvas) {
        canvas.setDrawFilter(mPaintFlagsDrawFilter);

        Drawable drawable = getDrawable();
        if (drawable == null) {
            super.onDraw(canvas);
            return;
        }

        // 把Bitmap处理为圆形的图
        if (drawable instanceof BitmapDrawable) {
            BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
            drawRoundBitmap(canvas, bitmapDrawable);
        } else {
            super.onDraw(canvas);
        }

        //根据需要画描边
        if (mStrokeWidth != 0) {
            mPaint.reset();
            mPaint.setAntiAlias(true);
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setColor(mStrokeColor);
            mPaint.setStrokeWidth(mStrokeWidth);
            canvas.drawRoundRect(mStrokeWidth, mStrokeWidth, getWidth() - mStrokeWidth, getHeight() - mStrokeWidth, mLeftRoundRadius, mRightRoundRadius, mPaint);
        }

        //根据需要绘制蒙版
        if (mDrawMask) {
            mPaint.reset();
            mPaint.setAntiAlias(true);
            mPaint.setStyle(Paint.Style.FILL);
            mPaint.setColor(mMaskColor);
            canvas.drawRoundRect(mStrokeWidth, mStrokeWidth,
                    getWidth() - mStrokeWidth, getHeight() - mStrokeWidth, mLeftRoundRadius, mRightRoundRadius, mPaint);
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private void drawRoundBitmap(Canvas canvas, BitmapDrawable bitmapDrawable) {
        Bitmap bitmap = bitmapDrawable.getBitmap();
        if (bitmap != null) {
            int drawBitmapWidth = getWidth() - mStrokeWidth;
            int drawBitmapHeight = getHeight() - mStrokeWidth;

            mBitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);

            //将bitmap缩放大小
            float maxScale = Math.max(drawBitmapHeight * 1.0f / bitmap.getHeight(), drawBitmapWidth * 1.0f / bitmap.getWidth());
            float minScale = Math.max(drawBitmapHeight * 1.0f / bitmap.getHeight(), drawBitmapWidth * 1.0f / bitmap.getWidth());

            if (mScaleMode == MAX_SCALE_MODE) {
                mBitmapMatrix.setScale(maxScale, maxScale);
            } else {
                mBitmapMatrix.setScale(minScale, minScale);
            }
            mBitmapShader.setLocalMatrix(mBitmapMatrix);

            //绘制缩放后的bitmap
            mPaint.reset();
            mPaint.setAntiAlias(true);
            mPaint.setShader(mBitmapShader);
            canvas.drawRoundRect(mStrokeWidth, mStrokeWidth,
                    getWidth() - mStrokeWidth, getHeight() - mStrokeWidth, mLeftRoundRadius, mRightRoundRadius, mPaint);
        }
    }

    public void setLeftRoundRadius(float leftRoundRadius) {
        mLeftRoundRadius = leftRoundRadius;
        invalidate();
    }

    public void setRightRoundRadius(float rightRoundRadius) {
        mRightRoundRadius = rightRoundRadius;
        invalidate();
    }

    public void setStrokeWidth(int strokeWidth) {
        mStrokeWidth = strokeWidth;
    }

    public void setStrokeColor(int strokeColor) {
        mStrokeColor = strokeColor;
        invalidate();
    }

    public void setMaskColor(int maskColor) {
        mMaskColor = maskColor;
        invalidate();
    }

    public void setDrawMask(boolean drawMask) {
        mDrawMask = drawMask;
        invalidate();
    }

    public void setScaleMode(int scaleMode) {
        mScaleMode = scaleMode;
        invalidate();
    }
}
